package cs294s.liveradar;

import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import com.google.android.maps.GeoPoint;

import cs294s.liveradar.data.Blip;
import cs294s.liveradar.data.Filter;
import cs294s.liveradar.service.FeedManager;
import cs294s.liveradar.service.FilterManager;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class FilterEditForm extends Activity {
	//These have to match the hints in the form
	static final String DEFAULT_RADIUS = "10";
	static final String DEFAULT_TIME = "5";
	
	static final int PICK_LOCATION_REQUEST = 0;

	private FilterManager filterManager;

	
	String currAddr;
	int currLat;
	int currLon;

	Geocoder geoCoder;
	
	Spinner distanceSpinner;
	Spinner timeSpinner;
	
	Filter filter;
	String currId = "";

	@Override
    public void onCreate(Bundle savedInstanceState) {
		
        super.onCreate(savedInstanceState);
        setContentView(R.layout.filtercreate);

		geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
        filterManager = FilterManager.getInstance(this);
  
        loadSpinners();
        setupButtons();
        
        loadFilter();
        
        
	}
	
	private void loadFilter() {
        int filterIndex = getIntent().getIntExtra("filterIndex", -1);
        if(filterIndex >= 0) {
        	filter = filterManager.get(filterIndex);
        	
        	currId = filter.getId();
        	//Tags - assumes comma separated values
    		EditText tagsInput = (EditText) findViewById(R.id.filtercreate_tagsText);
    		tagsInput.setText(filter.tagsToString());
    
    		//Name
    		EditText nameInput = (EditText) findViewById(R.id.filtercreate_nameText);  
    		nameInput.setText(filter.getName());
  
    		//Description
    		EditText descriptionInput = (EditText) findViewById(R.id.filtercreate_descriptionText);  
    		descriptionInput.setText(filter.getDescription());
    
    		//Center
    		currLat = filter.getCenter().getLatitudeE6();
    		currLon = filter.getCenter().getLongitudeE6();
    		showAddress();
    		
    		//Radius
    		EditText radiusInput = (EditText) findViewById(R.id.filtercreate_radiusText);  
    		radiusInput.setText(filter.getRadius().toString());
    		
    		//Distance Units
    		for(int i = 0; i < distanceSpinner.getCount(); i++) {
    			if(((String)distanceSpinner.getSelectedItem()).equals(filter.getDistanceUnits())) distanceSpinner.setSelection(i);
    		}
    		
    		//Time Range
    		EditText timeInput = (EditText) findViewById(R.id.filtercreate_timeText);  
    		timeInput.setText(filter.getTimeRange().toString());

    		//Time Units
    		for(int i = 0; i < timeSpinner.getCount(); i++) {
    			if(((String)timeSpinner.getSelectedItem()).equals(filter.getTimeUnits())) timeSpinner.setSelection(i);
    		}
    		
        }
	}
	
	
	private void loadSpinners() {
	    distanceSpinner = (Spinner) findViewById(R.id.filtercreate_distanceSpinner);
	    ArrayAdapter distanceAdapter = ArrayAdapter.createFromResource(
	            this, R.array.distance_units, android.R.layout.simple_spinner_item);
	    distanceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	    distanceSpinner.setAdapter(distanceAdapter);
	  
	    timeSpinner = (Spinner) findViewById(R.id.filtercreate_timeSpinner);
	    ArrayAdapter timeAdapter = ArrayAdapter.createFromResource(
	            this, R.array.time_units, android.R.layout.simple_spinner_item);
	    timeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	    timeSpinner.setAdapter(timeAdapter);
	    
	}
	
	private void setupButtons() {
		Button hereButton = (Button)findViewById(R.id.filtercreate_hereButton);
		Button mapButton = (Button)findViewById(R.id.filtercreate_mapButton);
		Button favsButton = (Button)findViewById(R.id.filtercreate_favsButton);

		Button confirmButton = (Button)findViewById(R.id.filtercreate_confirmButton);
		Button cancelButton = (Button)findViewById(R.id.filtercreate_cancelButton);

		hereButton.setOnClickListener(hereButtonOnClickListener);
		mapButton.setOnClickListener(mapButtonOnClickListener);
		favsButton.setOnClickListener(favsButtonOnClickListener);

		confirmButton.setOnClickListener(confirmButtonOnClickListener);
		cancelButton.setOnClickListener(cancelButtonOnClickListener);
	}
	
	


	private Button.OnClickListener hereButtonOnClickListener
	= new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			displayCurrentLocation();
		}
	};

	private Button.OnClickListener mapButtonOnClickListener
	= new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			Intent i = new Intent(getBaseContext(), LocationChooserMap.class);
			/*option: the initial locaiton*/
			i.putExtra("lat", currLat);
			i.putExtra("lon", currLon);

			startActivityForResult(i, PICK_LOCATION_REQUEST);
		}
	};

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent data) {
		if (requestCode == PICK_LOCATION_REQUEST) {
			if (resultCode == RESULT_OK) {
				currLat = data.getIntExtra("lat", 0);
				currLon = data.getIntExtra("lon", 0);
				currAddr = data.getStringExtra("addr");

				Log.d("RADAR", "RESULT" + currLat);
				EditText locationInput = (EditText) findViewById(R.id.filtercreate_locationText);
				locationInput.setText(currAddr);
			}
		}
	}

	
	private Button.OnClickListener favsButtonOnClickListener
	= new Button.OnClickListener(){
		@Override
		public void onClick(View v) {

		}
	};


	private Button.OnClickListener confirmButtonOnClickListener
	= new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			sendFilter();

		}
	};

	private Button.OnClickListener cancelButtonOnClickListener
	= new Button.OnClickListener(){
		@Override
		public void onClick(View v) {
			finish();
		}
	};


	private void displayCurrentLocation() {
		LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		Location l = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		
		if(l == null) 
			l = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
	
		if(l == null) {
			Toast.makeText(getBaseContext(), "Cannot detect current location", Toast.LENGTH_SHORT).show();
			return;
		}
		double lat = l.getLatitude();
		double lon = l.getLongitude();
		currLat = (int) (lat * 1E6); 
		currLon = (int) (lon * 1E6);
		
		showAddress();

	}
	
	private void showAddress() {
		try {
			List<Address> addresses = geoCoder.getFromLocation(currLat/(1E6),currLon/(1E6), 1);
			
			String add = "";
			if (addresses.size() > 0) 
				for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++)
					add += addresses.get(0).getAddressLine(i) + "\n";
			
			currAddr = add.trim();
			EditText locationInput = (EditText) findViewById(R.id.filtercreate_locationText);
			locationInput.setText(currAddr);
		} catch (IOException e) {
			e.printStackTrace();
			Toast.makeText(getBaseContext(), "Cannot retrieve address for current location", Toast.LENGTH_SHORT).show();
		} catch (IllegalArgumentException e) {
			Toast.makeText(getBaseContext(), "Cannot retrieve address", Toast.LENGTH_SHORT).show();
		}
	}
	
	
	private void sendFilter() {
		Button confirmButton = (Button)findViewById(R.id.filtercreate_confirmButton);
		confirmButton.setEnabled(false);
		Filter filter = collectFormData();
		if(filter != null) {
			filterManager.add(filter);
			Toast.makeText(getBaseContext(), "Filter Saved", Toast.LENGTH_SHORT).show();
		} else {
			confirmButton.setEnabled(true);
		}
	}
        
	
	private Filter collectFormData() {
		Filter f = new Filter();

		Calendar now = Calendar.getInstance();
		if(currId.length() == 0) currId = Long.toString(now.getTimeInMillis());
		
		f.setId(currId);
		
		//Tags - assumes comma separated values
		EditText tagsInput = (EditText) findViewById(R.id.filtercreate_tagsText);
		String tags= tagsInput.getText().toString();
		f.addTags(tags);

		//Name
		EditText nameInput = (EditText) findViewById(R.id.filtercreate_nameText);  
		String name = nameInput.getText().toString();
		f.setName(name);
		
		//Description
		EditText descriptionInput = (EditText) findViewById(R.id.filtercreate_descriptionText);  
		String description = descriptionInput.getText().toString();
		f.setDescription(description);

		//Center
		GeoPoint p = new GeoPoint(currLat, currLon);
		f.setCenter(p);

		//Radius
		EditText radiusInput = (EditText) findViewById(R.id.filtercreate_radiusText);  
		String radius = radiusInput.getText().toString();
		if(radius.length() == 0) radius = DEFAULT_RADIUS;
		try {
			f.setRadius(Double.parseDouble(radius));
		} catch (NumberFormatException e) {
			return badFilter("Please enter a valid distance.");
		}
		
		//Distance Units
		String distanceUnits = (String) distanceSpinner.getSelectedItem();
		f.setDistanceUnits(distanceUnits);
		
		//Time Range
		EditText timeInput = (EditText) findViewById(R.id.filtercreate_timeText);  
		String time = timeInput.getText().toString();
		if(time.length() == 0) time = DEFAULT_TIME;
		try {
			f.setTimeRange(Double.parseDouble(time));
		} catch (NumberFormatException e) {
			return badFilter("Please enter a valid time range.");
		}
		
		//Time Units
		String timeUnits = (String) timeSpinner.getSelectedItem();
		f.setTimeUnits(timeUnits);
		
		
		//Validate filter
		if(tags.length() <= 0)
			return badFilter("Please enter some tags.");
		if(name.length() <= 0)
			return badFilter("Please enter a name for this filter");
		if(description.length() <= 0) 
			return badFilter("Please enter a description for this filter");
		if(currLat == 0 && currLon == 0)
			return badFilter("Invalid location");
	
		return f;

	}
	
	private Filter badFilter(String msg) {
		Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
		return null;
	}
}
